<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)"><meta name="generator" content="Hexo 5.2.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.2/css/all.min.css" integrity="sha256-xejo6yLi6vGtAjcMIsY8BHdKsLg7QynVlFMzdQgUuy8=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.css" integrity="sha256-Vzbj7sDDS/woiFS3uNKo8eIuni59rjyNGtXfstRzStA=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"gz1234.gitee.io","root":"/","images":"/images","scheme":"Gemini","darkmode":true,"version":"8.12.3","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":true,"style":"flat"},"bookmark":{"enable":true,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta name="description" content="做一个 PC 端的网页，设计图是 1920X1080，要在常见屏上显示正常 ，比如：1280X720 1366X768 1440X900 1920X1080。就要使用 REM，width、height、margin、padding、left、top 都采用了 REM12345678910111213141516171819202122232425262728293031(function (win">
<meta property="og:type" content="article">
<meta property="og:title" content="js 代码片段实现">
<meta property="og:url" content="https://gz1234.gitee.io/2020/10/29/js-codeSnippet/index.html">
<meta property="og:site_name" content="郭泽">
<meta property="og:description" content="做一个 PC 端的网页，设计图是 1920X1080，要在常见屏上显示正常 ，比如：1280X720 1366X768 1440X900 1920X1080。就要使用 REM，width、height、margin、padding、left、top 都采用了 REM12345678910111213141516171819202122232425262728293031(function (win">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2020-10-29T03:05:28.000Z">
<meta property="article:modified_time" content="2023-06-30T09:45:22.741Z">
<meta property="article:author" content="郭泽">
<meta property="article:tag" content="js 代码片段实现">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="https://gz1234.gitee.io/2020/10/29/js-codeSnippet/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"https://gz1234.gitee.io/2020/10/29/js-codeSnippet/","path":"2020/10/29/js-codeSnippet/","title":"js 代码片段实现"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>js 代码片段实现 | 郭泽</title>
  





  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">郭泽</p>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%81%9A%E4%B8%80%E4%B8%AA-PC-%E7%AB%AF%E7%9A%84%E7%BD%91%E9%A1%B5%EF%BC%8C%E8%AE%BE%E8%AE%A1%E5%9B%BE%E6%98%AF-1920X1080%EF%BC%8C%E8%A6%81%E5%9C%A8%E5%B8%B8%E8%A7%81%E5%B1%8F%E4%B8%8A%E6%98%BE%E7%A4%BA%E6%AD%A3%E5%B8%B8-%EF%BC%8C%E6%AF%94%E5%A6%82%EF%BC%9A1280X720-1366X768-1440X900-1920X1080%E3%80%82%E5%B0%B1%E8%A6%81%E4%BD%BF%E7%94%A8-REM%EF%BC%8Cwidth%E3%80%81height%E3%80%81margin%E3%80%81padding%E3%80%81left%E3%80%81top-%E9%83%BD%E9%87%87%E7%94%A8%E4%BA%86-REM"><span class="nav-number">1.</span> <span class="nav-text">做一个 PC 端的网页，设计图是 1920X1080，要在常见屏上显示正常 ，比如：1280X720 1366X768 1440X900 1920X1080。就要使用 REM，width、height、margin、padding、left、top 都采用了 REM</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%B7%B1%E6%8B%B7%E8%B4%9D"><span class="nav-number">2.</span> <span class="nav-text">深拷贝</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#js-%E5%8E%9F%E6%9C%89%E7%9A%84-toFixed-%E5%87%BD%E6%95%B0%E5%BE%97%E5%88%B0%E7%BB%93%E6%9E%9C%E5%B9%B6%E9%9D%9E-%E6%83%B3%E8%A6%81%E7%9A%84-%E9%9C%80%E8%A6%81%E8%87%AA%E5%B7%B1%E9%87%8D%E6%96%B0%E5%AE%9A%E4%B9%89"><span class="nav-number">3.</span> <span class="nav-text">js 原有的 toFixed 函数得到结果并非 想要的 需要自己重新定义</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#bind-%E5%AE%9E%E7%8E%B0"><span class="nav-number">4.</span> <span class="nav-text">bind 实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#call-%E5%AE%9E%E7%8E%B0"><span class="nav-number">5.</span> <span class="nav-text">call 实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#apply-%E5%AE%9E%E7%8E%B0"><span class="nav-number">6.</span> <span class="nav-text">apply 实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%AE%80%E5%8D%95%E7%9A%84%E9%98%B2%E6%8A%96-%E5%87%BD%E6%95%B0"><span class="nav-number">7.</span> <span class="nav-text">简单的防抖 函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%8A%82%E6%B5%81"><span class="nav-number">8.</span> <span class="nav-text">节流</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#new-%E5%AE%9E%E7%8E%B0%E7%9A%84%E8%BF%87%E7%A8%8B"><span class="nav-number">9.</span> <span class="nav-text">new 实现的过程</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#compose-%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0-%E5%87%BD%E6%95%B0%E7%BB%84%E5%90%88"><span class="nav-number">10.</span> <span class="nav-text">compose 函数实现 函数组合</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#settimeout-%E6%A8%A1%E6%8B%9F%E5%AE%9E%E7%8E%B0-setinterval"><span class="nav-number">11.</span> <span class="nav-text">settimeout 模拟实现 setinterval</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8F%91%E5%B8%83%E8%AE%A2%E9%98%85%E6%A8%A1%E5%BC%8F"><span class="nav-number">12.</span> <span class="nav-text">发布订阅模式</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B8%B8%E7%94%A8%E6%8E%92%E5%BA%8F%E7%AE%97%E6%B3%95"><span class="nav-number">13.</span> <span class="nav-text">常用排序算法</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%86%92%E6%B3%A1%E6%8E%92%E5%BA%8F"><span class="nav-number">13.1.</span> <span class="nav-text">冒泡排序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%8F%92%E5%85%A5%E6%8E%92%E5%BA%8F"><span class="nav-number">13.2.</span> <span class="nav-text">　插入排序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BF%AB%E6%8E%92"><span class="nav-number">13.3.</span> <span class="nav-text">快排</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%BD%92%E5%B9%B6%E6%8E%92%E5%BA%8F"><span class="nav-number">13.4.</span> <span class="nav-text">归并排序</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%80%89%E6%8B%A9%E6%8E%92%E5%BA%8F"><span class="nav-number">13.5.</span> <span class="nav-text">选择排序</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%87%BD%E6%95%B0%E6%9F%AF%E7%B2%92%E5%8C%96-%E5%AE%9E%E7%8E%B0%E4%B8%80%E4%B8%AA-add-%E6%96%B9%E6%B3%95-add-1-2-3-6-add-1-2-3-4-10"><span class="nav-number">14.</span> <span class="nav-text">函数柯粒化 实现一个 add 方法 add(1)(2)(3)&#x3D;6 add(1,2,3)(4)&#x3D;10</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%83%B0%E6%80%A7%E5%87%BD%E6%95%B0"><span class="nav-number">15.</span> <span class="nav-text">惰性函数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%BC%93%E5%AD%98%E5%87%BD%E6%95%B0-%E9%80%92%E5%BD%92%E5%87%BD%E6%95%B0%E6%89%A7%E8%A1%8C%E4%BC%98%E5%8C%96"><span class="nav-number">16.</span> <span class="nav-text">缓存函数  递归函数执行优化</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#LRU-%E7%BC%93-%E5%AD%98-%E5%87%BD-%E6%95%B0"><span class="nav-number">17.</span> <span class="nav-text">LRU 缓 存 函 数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#instanceof-%E6%93%8D%E4%BD%9C%E7%AC%A6%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE%9E%E7%8E%B0"><span class="nav-number">18.</span> <span class="nav-text">instanceof  操作符的实现原理及实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%8E%A7%E5%88%B6%E5%BC%82%E6%AD%A5%E4%BB%BB%E5%8A%A1%E5%B9%B6%E5%8F%91%E6%95%B0%E9%87%8F"><span class="nav-number">19.</span> <span class="nav-text">控制异步任务并发数量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%9E%E7%8E%B0-Promise-all-race-allSettled-any"><span class="nav-number">20.</span> <span class="nav-text">实现 Promise.all&#x2F;race&#x2F;allSettled&#x2F;any</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%89%8D%E7%AB%AF%E9%87%8D%E6%96%B0%E9%83%A8%E7%BD%B2%E5%A6%82%E4%BD%95%E9%80%9A%E7%9F%A5%E7%94%A8%E6%88%B7%E5%88%B7%E6%96%B0%E7%BD%91%E9%A1%B5"><span class="nav-number">21.</span> <span class="nav-text">前端重新部署如何通知用户刷新网页</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#css-%E5%AE%9E%E7%8E%B0%E8%8A%82%E6%B5%81"><span class="nav-number">22.</span> <span class="nav-text">css 实现节流</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%B7%B1%E5%BA%A6%E4%BC%98%E5%85%88-DFS"><span class="nav-number">23.</span> <span class="nav-text">深度优先(DFS)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%B9%BF%E5%BA%A6%E4%BC%98%E5%85%88-BFS"><span class="nav-number">24.</span> <span class="nav-text">广度优先(BFS)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#js-%E5%8D%95%E4%BE%8B%E6%A8%A1%E5%BC%8F-proxy%E5%AE%9E%E7%8E%B0"><span class="nav-number">25.</span> <span class="nav-text">js 单例模式  proxy实现</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%B8%80%E9%94%AE%E9%BB%91%E7%99%BD"><span class="nav-number">26.</span> <span class="nav-text">一键黑白</span></a></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">郭泽</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">54</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">21</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">51</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>
  <a role="button" class="book-mark-link book-mark-link-fixed"></a>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="https://gz1234.gitee.io/2020/10/29/js-codeSnippet/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="郭泽">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="郭泽">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="js 代码片段实现 | 郭泽">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          js 代码片段实现
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2020-10-29 11:05:28" itemprop="dateCreated datePublished" datetime="2020-10-29T11:05:28+08:00">2020-10-29</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2023-06-30 17:45:22" itemprop="dateModified" datetime="2023-06-30T17:45:22+08:00">2023-06-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/js-%E4%BB%A3%E7%A0%81%E7%89%87%E6%AE%B5%E5%AE%9E%E7%8E%B0/" itemprop="url" rel="index"><span itemprop="name">js 代码片段实现</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h2 id="做一个-PC-端的网页，设计图是-1920X1080，要在常见屏上显示正常-，比如：1280X720-1366X768-1440X900-1920X1080。就要使用-REM，width、height、margin、padding、left、top-都采用了-REM"><a href="#做一个-PC-端的网页，设计图是-1920X1080，要在常见屏上显示正常-，比如：1280X720-1366X768-1440X900-1920X1080。就要使用-REM，width、height、margin、padding、left、top-都采用了-REM" class="headerlink" title="做一个 PC 端的网页，设计图是 1920X1080，要在常见屏上显示正常 ，比如：1280X720 1366X768 1440X900 1920X1080。就要使用 REM，width、height、margin、padding、left、top 都采用了 REM"></a>做一个 PC 端的网页，设计图是 1920X1080，要在常见屏上显示正常 ，比如：1280X720 1366X768 1440X900 1920X1080。就要使用 REM，width、height、margin、padding、left、top 都采用了 REM</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params">win</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> tid;</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">refreshRem</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> designSize = <span class="number">1920</span>; <span class="comment">// 设计图尺寸</span></span><br><span class="line">    <span class="keyword">let</span> html = <span class="built_in">document</span>.documentElement;</span><br><span class="line">    <span class="keyword">let</span> wW = html.clientWidth; <span class="comment">// 窗口宽度</span></span><br><span class="line">    <span class="keyword">let</span> rem = (wW * <span class="number">100</span>) / designSize;</span><br><span class="line">    <span class="built_in">document</span>.documentElement.style.fontSize = rem + <span class="string">&quot;px&quot;</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  win.addEventListener(</span><br><span class="line">    <span class="string">&quot;resize&quot;</span>,</span><br><span class="line">    <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="built_in">clearTimeout</span>(tid);</span><br><span class="line">      tid = <span class="built_in">setTimeout</span>(refreshRem, <span class="number">300</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="literal">false</span></span><br><span class="line">  );</span><br><span class="line">  win.addEventListener(</span><br><span class="line">    <span class="string">&quot;pageshow&quot;</span>,</span><br><span class="line">    <span class="function"><span class="keyword">function</span> (<span class="params">e</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (e.persisted) &#123;</span><br><span class="line">        <span class="built_in">clearTimeout</span>(tid);</span><br><span class="line">        tid = <span class="built_in">setTimeout</span>(refreshRem, <span class="number">300</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="literal">false</span></span><br><span class="line">  );</span><br><span class="line"></span><br><span class="line">  refreshRem();</span><br><span class="line">&#125;)(<span class="built_in">window</span>);</span><br></pre></td></tr></table></figure>

<p>计算 font-size 的逻辑是：<br>当设计图是 1920 时,规定 HTML 的 FONT-SIZE 的值是 100. 也就是,当浏览器窗口调整到 1920PX 时,1REM=100PX,如果要设定一个 160PX(1920 设计图时)的 margin-top,那么 REM 设置值是 1.6rem.</p>
<p><a target="_blank" rel="noopener" href="https://github.com/995231030/autofit.js">scale方案</a></p>
<h2 id="深拷贝"><a href="#深拷贝" class="headerlink" title="深拷贝"></a>深拷贝</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">deepClone</span>(<span class="params">origin, hashMap = <span class="keyword">new</span> <span class="built_in">WeakMap</span>()</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (origin == <span class="literal">undefined</span> || <span class="keyword">typeof</span> origin !== <span class="string">&quot;object&quot;</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> origin;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (origin <span class="keyword">instanceof</span> <span class="built_in">Date</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Date</span>(origin);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">if</span> (origin <span class="keyword">instanceof</span> <span class="built_in">RegExp</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">RegExp</span>(origin);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> hashKey = hashMap.get(origin);</span><br><span class="line">  <span class="keyword">if</span> (hashKey) &#123;</span><br><span class="line">    <span class="keyword">return</span> hashKey;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> target = <span class="keyword">new</span> origin.constructor();</span><br><span class="line">  hashMap.set(origin, target);</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">const</span> k <span class="keyword">in</span> origin) &#123;</span><br><span class="line">    <span class="keyword">if</span> (origin.hasOwnProperty(k)) &#123;</span><br><span class="line">      target[k] = deepClone(origin[k]);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> target;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params">obj</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 判断数据是否是复杂类型</span></span><br><span class="line">      <span class="keyword">if</span> (obj <span class="keyword">instanceof</span> <span class="built_in">Object</span>) &#123;</span><br><span class="line">        <span class="comment">//判断数据是否是数组</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">Array</span>.isArray(obj)) &#123;</span><br><span class="line">          <span class="comment">//声明一个空数组来接收拷贝后的数据</span></span><br><span class="line">          <span class="keyword">let</span> result = []</span><br><span class="line">          obj.forEach(<span class="function"><span class="params">item</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 需要递归深层遍历，否则复制的是地址</span></span><br><span class="line">            result.push(fn(item))</span><br><span class="line">          &#125;)</span><br><span class="line">          <span class="comment">// 返回输出这个数组,数组拷贝完成</span></span><br><span class="line">          <span class="keyword">return</span> result</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">//如果是对象,就声明一个空对象来接收拷贝后的数据</span></span><br><span class="line">          <span class="keyword">let</span> result = &#123;&#125;</span><br><span class="line">          <span class="keyword">for</span> (<span class="keyword">let</span> k <span class="keyword">in</span> obj) &#123;</span><br><span class="line">            <span class="comment">// 使用递归深层遍历</span></span><br><span class="line">            result[k] = fn(obj[k])</span><br><span class="line">          &#125;</span><br><span class="line">          <span class="comment">// 返回输出这个对象,对象拷贝完成</span></span><br><span class="line">          <span class="keyword">return</span> result</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="comment">// 简单数据类型则直接返回输出</span></span><br><span class="line">      <span class="keyword">return</span> obj</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>

<h2 id="js-原有的-toFixed-函数得到结果并非-想要的-需要自己重新定义"><a href="#js-原有的-toFixed-函数得到结果并非-想要的-需要自己重新定义" class="headerlink" title="js 原有的 toFixed 函数得到结果并非 想要的 需要自己重新定义"></a>js 原有的 toFixed 函数得到结果并非 想要的 需要自己重新定义</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">toFixed</span>(<span class="params">number, m</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> number !== <span class="string">&quot;number&quot;</span>) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">TypeError</span>(<span class="string">&quot;number不是数字&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">let</span> result = <span class="built_in">Math</span>.round(<span class="built_in">Math</span>.pow(<span class="number">10</span>, m) * number) / <span class="built_in">Math</span>.pow(<span class="number">10</span>, m);</span><br><span class="line">  result = <span class="built_in">String</span>(result);</span><br><span class="line">  <span class="keyword">if</span> (result.indexOf(<span class="string">&quot;.&quot;</span>) == -<span class="number">1</span>) &#123;</span><br><span class="line">    <span class="keyword">if</span> (m != <span class="number">0</span>) &#123;</span><br><span class="line">      result += <span class="string">&quot;.&quot;</span>;</span><br><span class="line">      result += <span class="keyword">new</span> <span class="built_in">Array</span>(m + <span class="number">1</span>).join(<span class="string">&quot;0&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">let</span> arr = result.split(<span class="string">&quot;.&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (arr[<span class="number">1</span>].length &lt; m) &#123;</span><br><span class="line">      arr[<span class="number">1</span>] += <span class="keyword">new</span> <span class="built_in">Array</span>(m - arr[<span class="number">1</span>].length + <span class="number">1</span>).join(<span class="string">&quot;0&quot;</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    result = arr.join(<span class="string">&quot;.&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<a id="more"></a>

<h2 id="bind-实现"><a href="#bind-实现" class="headerlink" title="bind 实现"></a>bind 实现</h2><p>实现函数的 bind ，同时考虑了一些其他情况</p>
<ul>
<li><p>函数作为构造函数用 new 关键字调用时，不应该改变其 this 指向，因为 new 绑定 的优先级高于 显示绑定 和 硬绑定</p>
</li>
<li><p>返回⼀个函数，绑定 this，传递预置参数</p>
</li>
<li><p>定义了绑定后函数的 length 属性和 name 属性（不可枚举属性）</p>
</li>
<li><p>绑定后函数的 prototype 需指向原函数的 prototype</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">const</span> iBind = <span class="function"><span class="keyword">function</span>(<span class="params">thisArg, ...args</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> originFunc = <span class="built_in">this</span>;</span><br><span class="line">  <span class="keyword">const</span> boundFunc = <span class="function"><span class="keyword">function</span>(<span class="params">...args1</span>) </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">let</span> nop = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;; <span class="comment">// 构建一个干净的函数，用于保存原函数的原型</span></span><br><span class="line">    <span class="comment">// 解决 bind 之后对返回函数 new 的问题</span></span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">new</span>.target) &#123;<span class="comment">// this instance boundFunc</span></span><br><span class="line">      <span class="keyword">const</span> res = originFunc.apply(<span class="built_in">this</span>, args.concat(args1));</span><br><span class="line">       <span class="keyword">if</span> (originFunc.prototype) &#123;</span><br><span class="line">        boundFunc.prototype = originFunc.prototype;</span><br><span class="line">      &#125; </span><br><span class="line">      <span class="keyword">return</span> res !== <span class="literal">null</span> &amp;&amp; (<span class="keyword">typeof</span> res === <span class="string">&#x27;object&#x27;</span> || <span class="keyword">typeof</span> res === <span class="string">&#x27;function&#x27;</span>) ? res : <span class="built_in">this</span>;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> originFunc.apply(thisArg, args.concat(args1));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 解决length 和 name 属性问题</span></span><br><span class="line">  <span class="keyword">const</span> desc = <span class="built_in">Object</span>.getOwnPropertyDescriptors(originFunc);</span><br><span class="line">  <span class="built_in">Object</span>.defineProperties(boundFunc, &#123;</span><br><span class="line">    length: <span class="built_in">Object</span>.assign(desc.length, &#123;</span><br><span class="line">      value: desc.length &lt; args.length ? <span class="number">0</span> : (desc.length - args.length)</span><br><span class="line">    &#125;),</span><br><span class="line">    name: <span class="built_in">Object</span>.assign(desc.name, &#123;</span><br><span class="line">      value: <span class="string">`bound <span class="subst">$&#123;desc.name.value&#125;</span>`</span></span><br><span class="line">    &#125;)</span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="keyword">return</span> boundFunc;</span><br><span class="line">&#125;;</span><br><span class="line"><span class="comment">// 保持 bind 的数据属性一致</span></span><br><span class="line"><span class="built_in">Object</span>.defineProperty(<span class="built_in">Function</span>.prototype, <span class="string">&#x27;iBind&#x27;</span>, &#123;</span><br><span class="line">  value: iBind,</span><br><span class="line">  enumerable: <span class="literal">false</span>,</span><br><span class="line">  configurable: <span class="literal">true</span>,</span><br><span class="line">  writable: <span class="literal">true</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br></pre></td></tr></table></figure>

</li>
</ul>
<h2 id="call-实现"><a href="#call-实现" class="headerlink" title="call 实现"></a>call 实现</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Function</span>.prototype.mycall = <span class="function"><span class="keyword">function</span> (<span class="params">thisArg</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// this指向调用call的对象</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">this</span> !== <span class="string">&quot;function&quot;</span>) &#123;</span><br><span class="line">    <span class="comment">// 调用call的若不是函数则报错</span></span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">TypeError</span>(<span class="string">&quot;不是一个函数&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> args = [...arguments].slice(<span class="number">1</span>);</span><br><span class="line">  thisArg = thisArg || <span class="built_in">window</span>;</span><br><span class="line">  <span class="comment">// 将调用call函数的对象添加到thisArg的属性中</span></span><br><span class="line">  thisArg.fn = <span class="built_in">this</span>;</span><br><span class="line">  <span class="comment">// 执行该属性</span></span><br><span class="line">  <span class="keyword">const</span> result = thisArg.fn(...arg);</span><br><span class="line">  <span class="comment">// 删除该属性</span></span><br><span class="line">  <span class="keyword">delete</span> thisArg.fn;</span><br><span class="line">  <span class="comment">// 返回函数执行结果</span></span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="apply-实现"><a href="#apply-实现" class="headerlink" title="apply 实现"></a>apply 实现</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Function</span>.prototype.myapply = <span class="function"><span class="keyword">function</span> (<span class="params">thisArg</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> <span class="built_in">this</span> !== <span class="string">&quot;function&quot;</span>) &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">TypeError</span>(<span class="string">&quot;不是一个函数&quot;</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> args = <span class="built_in">arguments</span>[<span class="number">1</span>];</span><br><span class="line"></span><br><span class="line">  thisArg.fn = <span class="built_in">this</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">const</span> result = thisArg.fn(...arg);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">delete</span> thisArg.fn;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="简单的防抖-函数"><a href="#简单的防抖-函数" class="headerlink" title="简单的防抖 函数"></a>简单的防抖 函数</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">debounce</span>(<span class="params">fn, delay = <span class="number">300</span></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> timer = <span class="literal">null</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> args = <span class="built_in">arguments</span>;</span><br><span class="line">    <span class="keyword">if</span> (timer) &#123;</span><br><span class="line">      <span class="built_in">clearTimeout</span>(timer);</span><br><span class="line">    &#125;</span><br><span class="line">    timer = <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      fn.apply(<span class="built_in">this</span>, args);</span><br><span class="line">    &#125;, delay);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="节流"><a href="#节流" class="headerlink" title="节流"></a>节流</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">throttle</span>(<span class="params">fn, delay</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> flag = <span class="literal">true</span>;</span><br><span class="line">  <span class="keyword">return</span> <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (!flag) <span class="keyword">return</span>;</span><br><span class="line">    flag = <span class="literal">false</span>;</span><br><span class="line">    timer = <span class="built_in">setTimeout</span>(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">      fn();</span><br><span class="line">      flag = <span class="literal">true</span>;</span><br><span class="line">    &#125;, delay);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="new-实现的过程"><a href="#new-实现的过程" class="headerlink" title="new 实现的过程"></a>new 实现的过程</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//因为new是关键字,函数的形式来实现，将构造函数和构造函数的参数传入</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myNew</span>(<span class="params">Fn, ...args</span>) </span>&#123;</span><br><span class="line">  <span class="comment">//1.创建一个空对象，并将对象的__proto__指向构造函数的prototype 这里我两步一起做了</span></span><br><span class="line">  <span class="keyword">const</span> obj = <span class="built_in">Object</span>.create(Fn.prototype);</span><br><span class="line">  <span class="comment">//2.将构造函数中的this指向obj，执行构造函数代码,获取返回值</span></span><br><span class="line">  <span class="keyword">const</span> res = Fn.apply(obj, args);</span><br><span class="line">  <span class="comment">//3.判断返回值类型</span></span><br><span class="line">  <span class="keyword">return</span> res <span class="keyword">instanceof</span> <span class="built_in">Object</span> ? res : obj;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="compose-函数实现-函数组合"><a href="#compose-函数实现-函数组合" class="headerlink" title="compose 函数实现 函数组合"></a>compose 函数实现 函数组合</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> (<span class="params">...fns</span>) </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">if</span>(<span class="params">!fns.length</span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">v</span>) =&gt;</span> v</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="title">if</span>(<span class="params">fns.length === <span class="number">1</span></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> fns[<span class="number">0</span>]</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> fns.reducer(<span class="function">(<span class="params">pre,cur</span>) =&gt;</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">...args</span>) =&gt;</span> pre(cur(...args))</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="settimeout-模拟实现-setinterval"><a href="#settimeout-模拟实现-setinterval" class="headerlink" title="settimeout 模拟实现 setinterval"></a>settimeout 模拟实现 setinterval</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">mySettimeout</span>(<span class="params">fn, t</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> timer = <span class="literal">null</span>;</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">interval</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    fn();</span><br><span class="line">    timer = <span class="built_in">setTimeout</span>(interval, t);</span><br><span class="line">  &#125;</span><br><span class="line">  interval();</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    cancel: <span class="function">() =&gt;</span> &#123;</span><br><span class="line">      <span class="built_in">clearTimeout</span>(timer);</span><br><span class="line">    &#125;,</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">mySetInterval</span>(<span class="params">fn, delay, times</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">let</span> timer = <span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        fn()</span><br><span class="line">        times--</span><br><span class="line">        timer = <span class="built_in">setTimeout</span>(a, delay)</span><br><span class="line">        <span class="keyword">if</span> (times &lt;= <span class="number">0</span>) &#123;</span><br><span class="line">            <span class="built_in">clearTimeout</span>(timer)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;, delay)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">mySetInterval(fn, <span class="number">2000</span>, <span class="number">3</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">//  requestAnimationFrame 实现setInterval</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">setInterval</span>(<span class="params">callback, interval</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> timer</span><br><span class="line">  <span class="keyword">const</span> now = <span class="built_in">Date</span>.now</span><br><span class="line">  <span class="keyword">let</span> startTime = now()</span><br><span class="line">  <span class="keyword">let</span> endTime = startTime</span><br><span class="line">  <span class="keyword">const</span> loop = <span class="function">() =&gt;</span> &#123;</span><br><span class="line">    timer = <span class="built_in">window</span>.requestAnimationFrame(loop)</span><br><span class="line">    endTime = now()</span><br><span class="line">    <span class="keyword">if</span> (endTime - startTime &gt;= interval) &#123;</span><br><span class="line">      startTime = endTime = now()</span><br><span class="line">      callback(timer)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  timer = <span class="built_in">window</span>.requestAnimationFrame(loop)</span><br><span class="line">  <span class="keyword">return</span> timer</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> a = <span class="number">0</span></span><br><span class="line"><span class="built_in">setInterval</span>(<span class="function"><span class="params">timer</span> =&gt;</span> &#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="number">1</span>)</span><br><span class="line">  a++</span><br><span class="line">  <span class="keyword">if</span> (a === <span class="number">3</span>) cancelAnimationFrame(timer)</span><br><span class="line">&#125;, <span class="number">1000</span>)</span><br></pre></td></tr></table></figure>

<h2 id="发布订阅模式"><a href="#发布订阅模式" class="headerlink" title="发布订阅模式"></a>发布订阅模式</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">EventEmitter</span> </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">constructor</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.events = &#123;&#125;;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 实现订阅</span></span><br><span class="line">  <span class="function"><span class="title">on</span>(<span class="params">type, callBack</span>)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="built_in">this</span>.events[type]) &#123;</span><br><span class="line">      <span class="built_in">this</span>.events[type] = [callBack];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="built_in">this</span>.events[type].push(callBack);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 删除订阅</span></span><br><span class="line">  <span class="function"><span class="title">off</span>(<span class="params">type, callBack</span>)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="built_in">this</span>.events[type]) <span class="keyword">return</span>;</span><br><span class="line">    <span class="built_in">this</span>.events[type] = <span class="built_in">this</span>.events[type].filter(<span class="function">(<span class="params">item</span>) =&gt;</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> item !== callBack;</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 只执行一次订阅事件</span></span><br><span class="line">  <span class="function"><span class="title">once</span>(<span class="params">type, callBack</span>)</span> &#123;</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      callBack();</span><br><span class="line">      <span class="built_in">this</span>.off(type, fn);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">this</span>.on(type, fn);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 触发事件</span></span><br><span class="line">  <span class="function"><span class="title">emit</span>(<span class="params">type, ...rest</span>)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.events[type] &amp;&amp;</span><br><span class="line">      <span class="built_in">this</span>.events[type].forEach(<span class="function">(<span class="params">fn</span>) =&gt;</span> fn.apply(<span class="built_in">this</span>, rest));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="常用排序算法"><a href="#常用排序算法" class="headerlink" title="常用排序算法"></a>常用排序算法</h2><p>JS 来说，数组长度大于 10 会采用快排，否则使用插入排序 <a target="_blank" rel="noopener" href="https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js#L760:7">源码实现</a> 。选择插入排序是因为虽然时间复杂度很差，但是在数据量很小的情况下和 <code>O(N * logN)</code>相差无几，然而插入排序需要的常数时间很小，所以相对别的排序来说更快。</p>
<h3 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h3><p>冒泡排序的原理如下，从第一个元素开始，把当前元素和下一个索引元素进行比较。如果当前元素大，那么就交换位置，重复操作直到比较到最后一个元素，那么此时最后一个元素就是该数组中最大的数。下一轮重复以上操作，但是此时最后一个元素已经是最大数了，所以不需要再比较最后一个元素</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bubbleSort</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 缓存数组长度</span></span><br><span class="line">  <span class="keyword">const</span> len = arr.length;</span><br><span class="line">  <span class="comment">// 外层循环用于控制从头到尾的比较+交换到底有多少轮</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; len; i++) &#123; </span><br><span class="line">    <span class="comment">// 每循环完一次就少一次比教</span></span><br><span class="line">    <span class="comment">// 内层循环用于完成每一轮遍历过程中的重复比较+交换 </span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> j = <span class="number">0</span>; j &lt; len - <span class="number">1</span> - i; j++) &#123;</span><br><span class="line">      <span class="comment">// 若相邻元素前面的数比后面的大</span></span><br><span class="line">      <span class="keyword">if</span> (arr[j] &gt; arr[j + <span class="number">1</span>]) &#123;</span><br><span class="line">        <span class="comment">// 交换两者</span></span><br><span class="line">        [arr[j], arr[j + <span class="number">1</span>]] = [arr[j + <span class="number">1</span>], arr[j]];</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="comment">// 返回数组</span></span><br><span class="line">  <span class="keyword">return</span> arr;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="插入排序"><a href="#插入排序" class="headerlink" title="　插入排序"></a>　插入排序</h3><p>第一个元素默认是已排序元素，取出下一个元素和当前元素比较，如果当前元素大就交换位置。那么此时第一个元素就是当前的最小数，所以下次取出操作从第三个元素开始，向前对比，重复之前的操作</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">insertSort</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">1</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">        <span class="comment">//当前要处理的数</span></span><br><span class="line">        <span class="keyword">let</span> temp = arr[i];</span><br><span class="line">        <span class="keyword">let</span> j = i - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span> (j &gt;= <span class="number">0</span> &amp;&amp; arr[j] &gt; temp) &#123;</span><br><span class="line">            <span class="comment">//如果前一个数大于后一个数,将前一个数往后移一位</span></span><br><span class="line">            arr[j + <span class="number">1</span>] = arr[j]</span><br><span class="line">            j--</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//此时的j是要处理的数排序后应该在的位置</span></span><br><span class="line">        arr[j+<span class="number">1</span>] = temp</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="快排"><a href="#快排" class="headerlink" title="快排"></a>快排</h3><p>分区: 从数组中任意选择一个基准，所有比基准小的元素放到基准前面，比基准大的元素放到基准的后面<br>递归：递归地对基准前后的子数组进行分区</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">quirkSort</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">  <span class="function"><span class="title">if</span>(<span class="params">arr.length &lt;= <span class="number">1</span></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">let</span> left = [];</span><br><span class="line">  <span class="keyword">let</span> right = [];</span><br><span class="line">  <span class="keyword">var</span> pivotIndex = <span class="built_in">Math</span>.floor(arr.length / <span class="number">2</span>);</span><br><span class="line">　<span class="keyword">var</span> pivot = arr.splice(pivotIndex, <span class="number">1</span>)[<span class="number">0</span>];</span><br><span class="line">　<span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++)&#123;</span><br><span class="line">　　　　<span class="keyword">if</span> (arr[i] &lt; pivot) &#123;</span><br><span class="line">　　　　　　left.push(arr[i]);</span><br><span class="line">　　　　&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">　　　　　　right.push(arr[i]);</span><br><span class="line">　　　　&#125;</span><br><span class="line">　　&#125;</span><br><span class="line">　　<span class="keyword">return</span> quickSort(left).concat([pivot], quickSort(right));</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h3 id="归并排序"><a href="#归并排序" class="headerlink" title="归并排序"></a>归并排序</h3><p>归并”的意思是将两个或两个以上的有序表组合成一个新的有序表。假如初始序列含有n个记录，则可看成是n个有序的子序列，每个子序列的长度为1，然后两两归并，得到[n/2]（向上取整）个长度为2或1的有序子序列；再两两归并，……，如此重复，直到得到一个长度为n的有序序列为止，这种排序方法称为2-路归并排序。</p>
<p>步骤解析：</p>
<p>1、把长度为n的输入序列分成两个长度为n/2的子序列；</p>
<p>2、对这两个子序列继续分为m/2的子序列，一直分下去，直为1个元素；</p>
<p>3、将两个排序好的子序列合并成一个最终的排序序列。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//归并排序</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">mergeSort</span>(<span class="params">arr</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> len = arr.length;</span><br><span class="line">  <span class="function"><span class="title">if</span>(<span class="params">len &lt; <span class="number">2</span></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> arr;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">//首先将无序数组划分为两个数组</span></span><br><span class="line">  <span class="keyword">var</span> mid = <span class="built_in">Math</span>.floor(len / <span class="number">2</span>);</span><br><span class="line">  <span class="keyword">var</span> left = arr.slice(<span class="number">0</span>,mid);</span><br><span class="line">  <span class="keyword">var</span> right = arr.slice(mid,len);</span><br><span class="line">  <span class="keyword">return</span> merge(mergeSort(left),mergeSort(right));<span class="comment">//递归分别对左右两部分数组进行排序合并</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//合并</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">merge</span>(<span class="params">left,right</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> result = [];</span><br><span class="line">  <span class="function"><span class="title">while</span>(<span class="params">left.length&gt;<span class="number">0</span> &amp;&amp; right.length&gt;<span class="number">0</span></span>)</span>&#123;</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params">left[<span class="number">0</span>]&lt;=right[<span class="number">0</span>]</span>)</span>&#123;</span><br><span class="line">      <span class="comment">//如果左边的数据小于右边的数据，将左边数据取出，放在新数组中</span></span><br><span class="line">      result.push(left.shift());</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">       result.push(right.shift());</span><br><span class="line">     &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="title">while</span>(<span class="params">left.length</span>)</span>&#123;</span><br><span class="line">     result.push(left.shift());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="title">while</span>(<span class="params">right.length</span>)</span>&#123;</span><br><span class="line">     result.push(right.shift());</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> arr = [<span class="number">3</span>,<span class="number">44</span>,<span class="number">38</span>,<span class="number">5</span>,<span class="number">47</span>,<span class="number">15</span>,<span class="number">36</span>,<span class="number">26</span>];</span><br><span class="line"><span class="built_in">console</span>.log(mergeSort(arr));<span class="comment">//3,5,15,26,36,38,44,47</span></span><br></pre></td></tr></table></figure>

<h3 id="选择排序"><a href="#选择排序" class="headerlink" title="选择排序"></a>选择排序</h3><p>找到数组中的最小值，选中它并将其放置在第一位<br>接着找到第二个最小值，选中它并将其放置到第二位<br>执行n-1轮，就可以完成排序</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Array</span>.prototype.selectionSort = <span class="function"><span class="keyword">function</span> <span class="title">selectionSort</span>(<span class="params"></span>) </span>&#123; </span><br><span class="line">    <span class="function"><span class="title">for</span>(<span class="params"><span class="keyword">let</span> i = <span class="number">0</span>; i &lt; <span class="built_in">this</span>.length - <span class="number">1</span>; ++i</span>)</span> &#123; </span><br><span class="line">        <span class="comment">// 假设最小的值是当前的下标</span></span><br><span class="line">        <span class="keyword">let</span> indexMin = i;</span><br><span class="line">        <span class="comment">//遍历剩余长度找到最小下标</span></span><br><span class="line">        <span class="function"><span class="title">for</span>(<span class="params"><span class="keyword">let</span> j = i; j &lt; <span class="built_in">this</span>.length; ++j</span>)</span> &#123; </span><br><span class="line">            <span class="function"><span class="title">if</span>(<span class="params"><span class="built_in">this</span>[j] &lt; <span class="built_in">this</span>[indexMin] </span>)</span> &#123; </span><br><span class="line">                indexMin = j;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="function"><span class="title">if</span>(<span class="params">indexMin !== i</span>)</span> &#123; </span><br><span class="line">            <span class="comment">//交换当前下标i与最小下标的值，重复this.length次</span></span><br><span class="line">            <span class="keyword">const</span> temp = <span class="built_in">this</span>[i];</span><br><span class="line">            <span class="built_in">this</span>[i] = <span class="built_in">this</span>[indexMin];</span><br><span class="line">            <span class="built_in">this</span>[indexMin] = temp;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> arr = [<span class="number">5</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>];</span><br><span class="line">arr.selectionSort();</span><br><span class="line"><span class="built_in">console</span>.log(arr);</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="函数柯粒化-实现一个-add-方法-add-1-2-3-6-add-1-2-3-4-10"><a href="#函数柯粒化-实现一个-add-方法-add-1-2-3-6-add-1-2-3-4-10" class="headerlink" title="函数柯粒化 实现一个 add 方法 add(1)(2)(3)=6 add(1,2,3)(4)=10"></a>函数柯粒化 实现一个 add 方法 add(1)(2)(3)=6 add(1,2,3)(4)=10</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">...args</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> allArgs = [...args];</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params">...newArgs</span>) </span>&#123;</span><br><span class="line">    allArgs = [...allArgs, ...newArgs];</span><br><span class="line">    <span class="keyword">return</span> fn;</span><br><span class="line">  &#125;</span><br><span class="line">  fn.toString = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!allArgs.length) &#123;</span><br><span class="line">      <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> allArgs.reduce(<span class="function">(<span class="params">sum, cur</span>) =&gt;</span> sum + cur);</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">return</span> fn;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 支持多参数传递</span></span><br><span class="line"><span class="comment">// 创建一个可以多步执行的柯里化函数，当参数满足数量时就去执行它：</span></span><br><span class="line"><span class="comment">// 函数公式：fn(x,y,z,w) ==&gt; fn(x)(y)(z)(w);</span></span><br><span class="line"><span class="keyword">let</span> createCurry = <span class="function">(<span class="params">fn,...params</span>)=&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">let</span> args = parsms || [];</span><br><span class="line">    <span class="keyword">let</span> fnLen = fn.length; <span class="comment">// 指定柯里化函数的参数长度</span></span><br><span class="line">    <span class="keyword">return</span> <span class="function">(<span class="params">...res</span>)=&gt;</span> &#123;</span><br><span class="line">        <span class="comment">// 通过作用域链获取上一次的所有参数</span></span><br><span class="line">        <span class="keyword">let</span> allArgs = args.slice(<span class="number">0</span>);</span><br><span class="line">        <span class="comment">// 深度拷贝闭包共用的args参数，避免后续操作影响（引用类型）</span></span><br><span class="line">        allArgs.push(...res);</span><br><span class="line">        <span class="function"><span class="title">if</span>(<span class="params">allArgs.length &lt; fnLen</span>)</span>&#123;</span><br><span class="line">           <span class="comment">// 当参数数量小于原函数的参数长度时，递归调用createCurry函数</span></span><br><span class="line">           <span class="keyword">return</span> createCurry.call(<span class="built_in">this</span>,fn,...allArgs);</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">          <span class="comment">// 当参数数量满足时，触发函数执行</span></span><br><span class="line">          <span class="keyword">return</span> fn.apply(<span class="built_in">this</span>,allArgs);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="惰性函数"><a href="#惰性函数" class="headerlink" title="惰性函数"></a>惰性函数</h2><p>惰性加载表示函数执行的分支只会在函数第一次调用的时候执行，在第一次调用的过程中 该函数被覆盖为另一个合适的方式执行的函数 这样任何对原函数的调用就不用再经过调用过的分支函调</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> getTime = <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>&#123;</span><br><span class="line">  <span class="keyword">var</span> time = <span class="keyword">new</span> <span class="built_in">Date</span>().getTime();</span><br><span class="line">  getTime = <span class="function"><span class="keyword">function</span> (<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">return</span> time</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> getTime()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(getTime());</span><br><span class="line"><span class="built_in">console</span>.log(getTime());</span><br><span class="line"><span class="built_in">console</span>.log(getTime());</span><br><span class="line"><span class="built_in">console</span>.log(getTime());</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="缓存函数-递归函数执行优化"><a href="#缓存函数-递归函数执行优化" class="headerlink" title="缓存函数  递归函数执行优化"></a>缓存函数  递归函数执行优化</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">memorize</span>(<span class="params">fn</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">let</span> cache = &#123;&#125;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> k = <span class="built_in">Array</span>.from(<span class="built_in">arguments</span>).join(<span class="string">&#x27;,&#x27;</span>);</span><br><span class="line">    <span class="keyword">return</span> cache[k] = cache[k] || fn.apply(<span class="built_in">this</span>,<span class="built_in">arguments</span>)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">fab</span>(<span class="params">m</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">return</span> m &lt;= <span class="number">2</span> ? <span class="number">1</span>: fab(m-<span class="number">1</span>) + fab(m-<span class="number">2</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> f = memorize(fab);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(f(<span class="number">8</span>));</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="LRU-缓-存-函-数"><a href="#LRU-缓-存-函-数" class="headerlink" title="LRU 缓 存 函 数"></a>LRU 缓 存 函 数</h2><p>LRU是Least Recently Used的缩写，即最近最少使用，是一种常用的页面置换算法[2]，选择最近最久未使用的页面予以淘汰。该算法赋予每个页面[3]一个访问字段，用来记录一个页面自上次被访问以来所经历的时间 t，当须淘汰一个页面时，选择现有页面中其 t 值最大的，即最近最少使用的页面予以淘汰。<br><a target="_blank" rel="noopener" href="https://baike.baidu.com/item/%E9%A1%B5%E9%9D%A2%E7%BD%AE%E6%8D%A2%E7%AE%97%E6%B3%95/7626091?fromModule=lemma_inlink">页面置换算法</a></p>
<p><a target="_blank" rel="noopener" href="https://baike.baidu.com/item/%E9%A1%B5%E9%9D%A2/5544813?fromModule=lemma_inlink">页面</a></p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">&#123;number&#125;</span> <span class="variable">capacity</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> LRUCache = <span class="function"><span class="keyword">function</span>(<span class="params">capacity</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// map是有序可排序的结构 js 中只能map实现</span></span><br><span class="line">    <span class="built_in">this</span>.map = <span class="keyword">new</span> <span class="built_in">Map</span>()</span><br><span class="line">    <span class="built_in">this</span>.capacity = capacity</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">&#123;number&#125;</span> <span class="variable">key</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">&#123;number&#125;</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">LRUCache.prototype.get = <span class="function"><span class="keyword">function</span>(<span class="params">key</span>) </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params"><span class="built_in">this</span>.map.has(key)</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">const</span> value = <span class="built_in">this</span>.map.get(key)</span><br><span class="line">        <span class="comment">// 更新存储位置</span></span><br><span class="line">        <span class="built_in">this</span>.map.delete(key)</span><br><span class="line">        <span class="built_in">this</span>.map.set(key,value)</span><br><span class="line">        <span class="keyword">return</span> value</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> - <span class="number">1</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">&#123;number&#125;</span> </span>key </span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param <span class="type">&#123;number&#125;</span> <span class="variable">value</span></span></span></span><br><span class="line"><span class="comment"> * <span class="doctag">@return <span class="type">&#123;void&#125;</span></span></span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">LRUCache.prototype.put = <span class="function"><span class="keyword">function</span>(<span class="params">key, value</span>) </span>&#123;</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params"><span class="built_in">this</span>.map.has(key)</span>)</span>&#123;</span><br><span class="line">        <span class="built_in">this</span>.map.delete(key)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">this</span>.map.set(key,value)</span><br><span class="line">    <span class="comment">// 如果此时超过了最长可存储范围</span></span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params"><span class="built_in">this</span>.map.size &gt; <span class="built_in">this</span>.capacity</span>)</span>&#123;</span><br><span class="line">        <span class="comment">// 删除 map 中最久未使用的元素</span></span><br><span class="line">        <span class="built_in">this</span>.map.delete(<span class="built_in">this</span>.map.keys().next().value)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="instanceof-操作符的实现原理及实现"><a href="#instanceof-操作符的实现原理及实现" class="headerlink" title="instanceof  操作符的实现原理及实现"></a>instanceof  操作符的实现原理及实现</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">myInstanceof</span>(<span class="params">left, right</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> proto = <span class="built_in">Object</span>.getPrototypeOf(left);</span><br><span class="line">  <span class="keyword">let</span> prototype = right.prototype;</span><br><span class="line">  <span class="function"><span class="title">while</span>(<span class="params"><span class="literal">true</span></span>)</span>&#123;</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params">!proto</span>)</span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params">proto === prototype</span>)</span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    proto = <span class="built_in">Object</span>.getPrototypeOf(proto)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="控制异步任务并发数量"><a href="#控制异步任务并发数量" class="headerlink" title="控制异步任务并发数量"></a>控制异步任务并发数量</h2><p>在 <code>urls</code> 数组中存放了 10 个接口地址。同时还定义了一个 <code>loadDate</code> 函数，这个函数接受一个 <code>url</code> 参数，返回一个 <code>Promise</code> 对象，该 <code>Promise</code> 在接口调用成功时返回 <code>resolve</code>，失败时返回 <code>reject</code>。要求：任意时刻，同时下载的链接数量不可以超过 3 个</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> urls = [</span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/1&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/2&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/3&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/4&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/5&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/6&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/7&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/8&#x27;</span>,</span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/9&#x27;</span>, </span><br><span class="line">  <span class="string">&#x27;http://jsonplaceholder.typicode.com/posts/10&#x27;</span></span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">loadDate</span> (<span class="params">url</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> xhr = <span class="keyword">new</span> XMLHttpRequest()</span><br><span class="line">    xhr.onload = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">      resolve(xhr.responseText)</span><br><span class="line">    &#125;</span><br><span class="line">    xhr.open(<span class="string">&#x27;GET&#x27;</span>, url)</span><br><span class="line">    xhr.send()</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">limitLoad</span>(<span class="params">urls, handler, limit</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 对数组进行一个拷贝</span></span><br><span class="line">    <span class="keyword">const</span> sequence = [].concat(urls)</span><br><span class="line">    <span class="keyword">let</span> promises = [];</span><br><span class="line"></span><br><span class="line">    <span class="comment">//实现并发请求达到最大值</span></span><br><span class="line">    promises = sequence.splice(<span class="number">0</span>, limit).map(<span class="function">(<span class="params">url, index</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="comment">// 这里返回的 index 是任务在数组 promises 的脚标</span></span><br><span class="line">        <span class="comment">//用于在 Promise.race 后找到完成的任务脚标</span></span><br><span class="line">        <span class="keyword">return</span> handler(url).then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> index</span><br><span class="line">        &#125;); </span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 利用数组的 reduce 方法来以队列的形式执行</span></span><br><span class="line">    <span class="keyword">return</span> sequence.reduce(<span class="function">(<span class="params">last, url, currentIndex</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> last.then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 返回最快改变状态的 Promise</span></span><br><span class="line">            <span class="keyword">return</span> <span class="built_in">Promise</span>.race(promises)</span><br><span class="line">        &#125;).catch(<span class="function"><span class="params">err</span> =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 这里的 catch 不仅用来捕获前面 then 方法抛出的错误</span></span><br><span class="line">            <span class="comment">// 更重要的是防止中断整个链式调用</span></span><br><span class="line">            <span class="built_in">console</span>.error(err)</span><br><span class="line">        &#125;).then(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">            <span class="comment">// 用新的 Promise 替换掉最快改变状态的 Promise</span></span><br><span class="line">            promises[res] = handler(sequence[currentIndex]).then(</span><br><span class="line">                () =&gt; &#123; <span class="keyword">return</span> res &#125;);</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;, <span class="built_in">Promise</span>.resolve()).then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">Promise</span>.all(promises)</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">用 Promise.race来实现，先并发请求3个图片资源，这样可以得到 3 个 Promise实例，组成一个数组promises ，</span></span><br><span class="line"><span class="comment">然后不断的调用 Promise.race 来返回最快改变状态的 Promise，然后从数组（promises ）中删掉这个 Promise 对象实例，</span></span><br><span class="line"><span class="comment">再加入一个新的 Promise实例，直到全部的 url 被取完。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">limitLoad</span>(<span class="params">urls, handler, limit</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 对数组做一个拷贝</span></span><br><span class="line">    <span class="keyword">const</span> sequence = [].concat(urls)</span><br><span class="line">    <span class="keyword">let</span> promises = [];</span><br><span class="line"></span><br><span class="line">    <span class="comment">//并发请求到最大数</span></span><br><span class="line">    promises = sequence.splice(<span class="number">0</span>, limit).map(<span class="function">(<span class="params">url, index</span>) =&gt;</span> &#123;</span><br><span class="line">        <span class="comment">// 这里返回的 index 是任务在 promises 的脚标，</span></span><br><span class="line">        <span class="comment">//用于在 Promise.race 之后找到完成的任务脚标</span></span><br><span class="line">        <span class="keyword">return</span> handler(url).then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> index</span><br><span class="line">        &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    (<span class="keyword">async</span> <span class="function"><span class="keyword">function</span> <span class="title">loop</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">let</span> p = <span class="built_in">Promise</span>.race(promises);</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; sequence.length; i++) &#123;</span><br><span class="line">            p = p.then(<span class="function">(<span class="params">res</span>) =&gt;</span> &#123;</span><br><span class="line">                promises[res] = handler(sequence[i]).then(<span class="function">() =&gt;</span> &#123;</span><br><span class="line">                    <span class="keyword">return</span> res</span><br><span class="line">                &#125;);</span><br><span class="line">                <span class="keyword">return</span> <span class="built_in">Promise</span>.race(promises)</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">limitLoad(urls, loadDate, <span class="number">3</span>)</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">因为 loadDate 函数也返回一个 Promise</span></span><br><span class="line"><span class="comment">所以当 所有图片加载完成后可以继续链式调用</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">limitLoad(urls, loadDate, 3).then(() =&gt; &#123;</span></span><br><span class="line"><span class="comment">    console.log(&#x27;所有url数据请求成功&#x27;);</span></span><br><span class="line"><span class="comment">&#125;).catch(err =&gt; &#123;</span></span><br><span class="line"><span class="comment">    console.error(err);</span></span><br><span class="line"><span class="comment">&#125;)</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h2 id="实现-Promise-all-race-allSettled-any"><a href="#实现-Promise-all-race-allSettled-any" class="headerlink" title="实现 Promise.all/race/allSettled/any"></a>实现 Promise.all/race/allSettled/any</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 有一个失败则返回失败的结果，全部成功返回全成功的数组</span></span><br><span class="line"><span class="built_in">Promise</span>.all = <span class="function"><span class="keyword">function</span> (<span class="params">promiseList = []</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> result = []</span><br><span class="line">    <span class="keyword">let</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">if</span> (promiseList.length === <span class="number">0</span>) &#123;</span><br><span class="line">      resolve(result)</span><br><span class="line">      <span class="keyword">return</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; promiseList.length; i++) &#123;</span><br><span class="line">      <span class="built_in">Promise</span>.resolve(promiseList[i]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">        result[i] = res</span><br><span class="line">        count++</span><br><span class="line">        <span class="comment">// 不能直接通过 result.length 进行比较，因为 会存在下标大的先赋值</span></span><br><span class="line">        <span class="comment">// 例如 i = 3 第一个返回结果，此时数组变为[empty,empty,empty,res]</span></span><br><span class="line">        <span class="keyword">if</span> (count === promiseList.length) &#123;</span><br><span class="line">          resolve(result)</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;).catch(<span class="function"><span class="params">e</span> =&gt;</span> &#123;</span><br><span class="line">        reject(e)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 返回第一个成功或失败的结果</span></span><br><span class="line"><span class="built_in">Promise</span>.race = <span class="function"><span class="keyword">function</span> (<span class="params">promiseList = []</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (promiseList.length === <span class="number">0</span>) &#123;</span><br><span class="line">      <span class="keyword">return</span> resolve([])</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; promiseList.length; i++) &#123;</span><br><span class="line">      <span class="built_in">Promise</span>.resolve(promiseList[i]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">        resolve(res)</span><br><span class="line">      &#125;).catch(<span class="function"><span class="params">e</span> =&gt;</span> &#123;</span><br><span class="line">        reject(e)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// 无论成功约否都返回，但是会添加一个 status 字段用于标记成功/失败</span></span><br><span class="line"><span class="built_in">Promise</span>.allSettled = <span class="function"><span class="keyword">function</span> (<span class="params">promiseList = []</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">const</span> result = []</span><br><span class="line">    <span class="keyword">let</span> count = <span class="number">0</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">const</span> addRes = <span class="function">(<span class="params">i, data</span>) =&gt;</span> &#123;</span><br><span class="line">      result[i] = data</span><br><span class="line">      count++</span><br><span class="line">      <span class="keyword">if</span> (count === promiseList.length) &#123;</span><br><span class="line">        resolve(result)</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (promiseList.length === <span class="number">0</span>) <span class="keyword">return</span> resolve(result)</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; promiseList.length; i++) &#123;</span><br><span class="line">      <span class="built_in">Promise</span>.resolve(promiseList[i]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">        addRes(i, &#123; <span class="attr">status</span>: <span class="string">&#x27;fulfilled&#x27;</span>, <span class="attr">data</span>: res &#125;)</span><br><span class="line">      &#125;).catch(<span class="function"><span class="params">e</span> =&gt;</span> &#123;</span><br><span class="line">        addRes(i, &#123; <span class="attr">status</span>: <span class="string">&#x27;rejected&#x27;</span>, <span class="attr">data</span>: e &#125;)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">// AggregateError，当多个错误需要包装在一个错误中时，该对象表示一个错误。</span></span><br><span class="line"><span class="comment">// 和 Promise.all 相反，全部失败返回失败的结果数组，有一个成功则返回成功结果</span></span><br><span class="line"><span class="built_in">Promise</span>.any = <span class="function"><span class="keyword">function</span> (<span class="params">promiseList = []</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function">(<span class="params">resolve, reject</span>) =&gt;</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (promiseList.length === <span class="number">0</span>) <span class="keyword">return</span> resolve([])</span><br><span class="line">    <span class="keyword">let</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">const</span> result = []</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">let</span> i = <span class="number">0</span>; i &lt; promiseList.length; i++) &#123;</span><br><span class="line">      <span class="built_in">Promise</span>.resolve(promiseList[i]).then(<span class="function"><span class="params">res</span> =&gt;</span> &#123;</span><br><span class="line">        resolve(res)</span><br><span class="line">      &#125;).catch(<span class="function"><span class="params">e</span> =&gt;</span> &#123;</span><br><span class="line">        count++</span><br><span class="line">        result[i] = e</span><br><span class="line">        <span class="keyword">if</span> (count === promiseList.length) &#123;</span><br><span class="line">          reject(<span class="keyword">new</span> AggregateError(result))</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="前端重新部署如何通知用户刷新网页"><a href="#前端重新部署如何通知用户刷新网页" class="headerlink" title="前端重新部署如何通知用户刷新网页"></a>前端重新部署如何通知用户刷新网页</h2><figure class="highlight typescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">interface</span> Options &#123;</span><br><span class="line">    timer?: <span class="built_in">number</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">Updater</span> </span>&#123;</span><br><span class="line">    oldScript: <span class="built_in">string</span>[] <span class="comment">//存储第一次值也就是script 的hash 信息</span></span><br><span class="line">    newScript: <span class="built_in">string</span>[] <span class="comment">//获取新的值 也就是新的script 的hash信息</span></span><br><span class="line">    dispatch: Record&lt;<span class="built_in">string</span>, <span class="built_in">Function</span>[]&gt; <span class="comment">//小型发布订阅通知用户更新了</span></span><br><span class="line">    <span class="function"><span class="title">constructor</span>(<span class="params">options: Options</span>)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.oldScript = [];</span><br><span class="line">        <span class="built_in">this</span>.newScript = []</span><br><span class="line">        <span class="built_in">this</span>.dispatch = &#123;&#125;</span><br><span class="line">        <span class="built_in">this</span>.init() <span class="comment">//初始化</span></span><br><span class="line">        <span class="built_in">this</span>.timing(options?.timer)<span class="comment">//轮询</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">async</span> <span class="function"><span class="title">init</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> html: <span class="built_in">string</span> = <span class="keyword">await</span> <span class="built_in">this</span>.getHtml()</span><br><span class="line">        <span class="built_in">this</span>.oldScript = <span class="built_in">this</span>.parserScript(html)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">async</span> <span class="function"><span class="title">getHtml</span>(<span class="params"></span>)</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> html = <span class="keyword">await</span> fetch(<span class="string">&#x27;/&#x27;</span>).then(<span class="function"><span class="params">res</span> =&gt;</span> res.text());<span class="comment">//读取index html</span></span><br><span class="line">        <span class="keyword">return</span> html</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="title">parserScript</span>(<span class="params">html: <span class="built_in">string</span></span>)</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> reg = <span class="keyword">new</span> <span class="built_in">RegExp</span>(<span class="regexp">/&lt;script(?:\s+[^&gt;]*)?&gt;(.*?)&lt;\/script\s*&gt;/ig</span>) <span class="comment">//script正则</span></span><br><span class="line">        <span class="keyword">return</span> html.match(reg) <span class="keyword">as</span> <span class="built_in">string</span>[] <span class="comment">//匹配script标签</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//发布订阅通知</span></span><br><span class="line">    <span class="function"><span class="title">on</span>(<span class="params">key: <span class="string">&#x27;no-update&#x27;</span> | <span class="string">&#x27;update&#x27;</span>, fn: <span class="built_in">Function</span></span>)</span> &#123;</span><br><span class="line">        (<span class="built_in">this</span>.dispatch[key] || (<span class="built_in">this</span>.dispatch[key] = [])).push(fn)  </span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="title">compare</span>(<span class="params">oldArr: <span class="built_in">string</span>[], newArr: <span class="built_in">string</span>[]</span>)</span> &#123;</span><br><span class="line">        <span class="keyword">const</span> base = oldArr.length</span><br><span class="line">        <span class="keyword">const</span> arr = <span class="built_in">Array</span>.from(<span class="keyword">new</span> <span class="built_in">Set</span>(oldArr.concat(newArr)))</span><br><span class="line">        <span class="comment">//如果新旧length 一样无更新</span></span><br><span class="line">        <span class="keyword">if</span> (arr.length === base) &#123;</span><br><span class="line">            <span class="built_in">this</span>.dispatch[<span class="string">&#x27;no-update&#x27;</span>].forEach(<span class="function"><span class="params">fn</span> =&gt;</span> &#123;</span><br><span class="line">                fn()</span><br><span class="line">            &#125;)</span><br><span class="line">        </span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="comment">//否则通知更新</span></span><br><span class="line">            <span class="built_in">this</span>.dispatch[<span class="string">&#x27;update&#x27;</span>].forEach(<span class="function"><span class="params">fn</span> =&gt;</span> &#123;</span><br><span class="line">                fn()</span><br><span class="line">            &#125;)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="title">timing</span>(<span class="params">time = <span class="number">10000</span></span>)</span> &#123;</span><br><span class="line">         <span class="comment">//轮询</span></span><br><span class="line">        <span class="built_in">setInterval</span>(<span class="keyword">async</span> () =&gt; &#123;</span><br><span class="line">            <span class="keyword">const</span> newHtml = <span class="keyword">await</span> <span class="built_in">this</span>.getHtml()</span><br><span class="line">            <span class="built_in">this</span>.newScript = <span class="built_in">this</span>.parserScript(newHtml)</span><br><span class="line">            <span class="built_in">this</span>.compare(<span class="built_in">this</span>.oldScript, <span class="built_in">this</span>.newScript)</span><br><span class="line">        &#125;, time)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//实例化该类</span></span><br><span class="line"><span class="keyword">const</span> up = <span class="keyword">new</span> Updater(&#123;</span><br><span class="line">    timer:<span class="number">2000</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//未更新通知</span></span><br><span class="line">up.on(<span class="string">&#x27;no-update&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">   <span class="built_in">console</span>.log(<span class="string">&#x27;未更新&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"><span class="comment">//更新通知</span></span><br><span class="line">up.on(<span class="string">&#x27;update&#x27;</span>,<span class="function">()=&gt;</span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;更新了&#x27;</span>)</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="css-实现节流"><a href="#css-实现节流" class="headerlink" title="css 实现节流"></a>css 实现节流</h2><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">button</span>&#123;</span><br><span class="line">  <span class="attribute">animation</span>: throttle <span class="number">2s</span> step-end forwards;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-tag">button</span><span class="selector-pseudo">:active</span>&#123;</span><br><span class="line">  <span class="attribute">animation</span>: none;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">@keyframes</span> throttle &#123;</span><br><span class="line">  <span class="selector-tag">from</span> &#123;</span><br><span class="line">    <span class="attribute">pointer-events</span>: none;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="selector-tag">to</span> &#123;</span><br><span class="line">    <span class="attribute">pointer-events</span>: all;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="深度优先-DFS"><a href="#深度优先-DFS" class="headerlink" title="深度优先(DFS)"></a>深度优先(DFS)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">dfs</span>(<span class="params">node</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(node.name);</span><br><span class="line">  node.children &amp;&amp;</span><br><span class="line">    node.children.forEach(<span class="function">(<span class="params">child</span>) =&gt;</span> &#123;</span><br><span class="line">      dfs(child);</span><br><span class="line">    &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 以栈的形式完成dfs</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">dfs1</span>(<span class="params">node</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">let</span> stack = [];</span><br><span class="line">  stack.push(node);</span><br><span class="line">  <span class="function"><span class="title">while</span>(<span class="params">stack.length&gt;<span class="number">0</span></span>)</span>&#123;</span><br><span class="line">    <span class="keyword">let</span> current = stack.pop();</span><br><span class="line">    <span class="function"><span class="title">if</span>(<span class="params">!!!current</span>)</span>&#123;</span><br><span class="line">      <span class="keyword">break</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">console</span>.log(current.name)</span><br><span class="line">    <span class="keyword">let</span> children = current.children || [];</span><br><span class="line">    <span class="comment">// 子节点反转入栈</span></span><br><span class="line">     <span class="function"><span class="title">if</span>(<span class="params">children.length&gt;<span class="number">0</span></span>)</span> &#123;</span><br><span class="line">      children.reverse().forEach(<span class="function">(<span class="params">item</span>) =&gt;</span>&#123;</span><br><span class="line">        stack.push(item)</span><br><span class="line">      &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> root = &#123;</span><br><span class="line">  name: <span class="string">&quot;A&quot;</span>,</span><br><span class="line">  children: [</span><br><span class="line">    &#123;</span><br><span class="line">      name: <span class="string">&quot;B&quot;</span>,</span><br><span class="line">      children: [&#123; <span class="attr">name</span>: <span class="string">&quot;B1&quot;</span> &#125;, &#123; <span class="attr">name</span>: <span class="string">&quot;B2&quot;</span> &#125;],</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name: <span class="string">&quot;C&quot;</span>,</span><br><span class="line">      children: [&#123; <span class="attr">name</span>: <span class="string">&quot;C1&quot;</span> &#125;, &#123; <span class="attr">name</span>: <span class="string">&quot;C2&quot;</span> &#125;],</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;;</span><br><span class="line">dfs1(root); </span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="广度优先-BFS"><a href="#广度优先-BFS" class="headerlink" title="广度优先(BFS)"></a>广度优先(BFS)</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bfs</span>(<span class="params">node</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">const</span> stack = [];</span><br><span class="line">  stack.push(node);</span><br><span class="line">  <span class="keyword">let</span> current;</span><br><span class="line">  <span class="keyword">while</span> ((current = stack.shift())) &#123;</span><br><span class="line">    <span class="built_in">console</span>.log(current.name);</span><br><span class="line">    current.children &amp;&amp;</span><br><span class="line">      current.children.forEach(<span class="function">(<span class="params">child</span>) =&gt;</span> &#123;</span><br><span class="line">        stack.push(child);</span><br><span class="line">      &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> root = &#123;</span><br><span class="line">  name: <span class="string">&quot;A&quot;</span>,</span><br><span class="line">  children: [</span><br><span class="line">    &#123;</span><br><span class="line">      name: <span class="string">&quot;B&quot;</span>,</span><br><span class="line">      children: [&#123; <span class="attr">name</span>: <span class="string">&quot;B1&quot;</span> &#125;, &#123; <span class="attr">name</span>: <span class="string">&quot;B2&quot;</span> &#125;],</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">      name: <span class="string">&quot;C&quot;</span>,</span><br><span class="line">      children: [&#123; <span class="attr">name</span>: <span class="string">&quot;C1&quot;</span> &#125;, &#123; <span class="attr">name</span>: <span class="string">&quot;C2&quot;</span> &#125;],</span><br><span class="line">    &#125;,</span><br><span class="line">  ],</span><br><span class="line">&#125;;</span><br><span class="line">bfs(root);</span><br></pre></td></tr></table></figure>

<h2 id="js-单例模式-proxy实现"><a href="#js-单例模式-proxy实现" class="headerlink" title="js 单例模式  proxy实现"></a>js 单例模式  proxy实现</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">singleton</span>(<span class="params">className</span>)</span>&#123;</span><br><span class="line">  <span class="keyword">let</span> ins;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Proxy</span>(className,&#123;</span><br><span class="line">    <span class="function"><span class="title">construct</span>(<span class="params">target,args</span>)</span>&#123;</span><br><span class="line">      <span class="function"><span class="title">if</span>(<span class="params">!ins</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> target(...args)</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> ins</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="一键黑白"><a href="#一键黑白" class="headerlink" title="一键黑白"></a>一键黑白</h2><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">    <span class="keyword">var</span> navStr = navigator.userAgent.toLowerCase();</span><br><span class="line">    <span class="keyword">if</span>(navStr.indexOf(<span class="string">&quot;msie 10.0&quot;</span>)!==-<span class="number">1</span>||navStr.indexOf(<span class="string">&quot;rv:11.0&quot;</span>)!==-<span class="number">1</span>)&#123; <span class="comment">// 判断是IE10或者IE11</span></span><br><span class="line">        grayscale(<span class="built_in">document</span>.body);</span><br><span class="line">        grayscale(<span class="built_in">document</span>.getElementsByTagName(<span class="string">&quot;img&quot;</span>));</span><br><span class="line">        <span class="built_in">document</span>.getElementsByTagName(<span class="string">&#x27;body&#x27;</span>)[<span class="number">0</span>].className = <span class="string">&#x27;bodyGrey&#x27;</span>; <span class="comment">//加类名</span></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">var</span> style = <span class="built_in">document</span>.createElement(<span class="string">&quot;style&quot;</span>);</span><br><span class="line">    style.type = <span class="string">&quot;text/css&quot;</span>;</span><br><span class="line">    style.innerHTML=<span class="string">&quot;body &#123;filter:gray;filter: grayscale(100%);-webkit-filter:grayscale(100%);filter:gray;filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)&#125;&quot;</span></span><br><span class="line">    style.id=<span class="string">&quot;addStyle&quot;</span></span><br><span class="line">    <span class="built_in">document</span>.getElementsByTagName(<span class="string">&quot;HEAD&quot;</span>).item(<span class="number">0</span>).appendChild(style);</span><br><span class="line">&lt;/script&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script><script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script><script defer="true" type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.js"></script><link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.css">
    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/js-%E4%BB%A3%E7%A0%81%E7%89%87%E6%AE%B5%E5%AE%9E%E7%8E%B0/" rel="tag"># js 代码片段实现</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/react%E9%9D%A2%E8%AF%95%E9%A2%98/" rel="prev" title="react面试题">
                  <i class="fa fa-chevron-left"></i> react面试题
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2020/10/29/%E5%89%8D%E7%AB%AF%E9%9D%A2%E8%AF%95%E9%A2%98/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80%E9%9D%A2%E8%AF%95%E9%A2%98/" rel="next" title="计算机基础面试题">
                  计算机基础面试题 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">郭泽</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/" rel="noopener" target="_blank">NexT.Gemini</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/fancybox/3.5.7/jquery.fancybox.min.js" integrity="sha256-yt2kYMy0w8AbtF89WXb2P1rfjcP/HTHLT7097U8Y5b8=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script><script src="/js/bookmark.js"></script>

  
<script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.0/search.js" integrity="sha256-vXZMYLEqsROAXkEw93GGIvaB2ab+QW6w3+1ahD9nXXA=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>

  <script class="next-config" data-name="pdf" type="application/json">{"object_url":{"url":"https://cdnjs.cloudflare.com/ajax/libs/pdfobject/2.2.8/pdfobject.min.js","integrity":"sha256-tu9j5pBilBQrWSDePOOajCUdz6hWsid/lBNzK4KgEPM="},"url":"/lib/pdf/web/viewer.html"}</script>
  <script src="/js/third-party/tags/pdf.js"></script>

  <script class="next-config" data-name="mermaid" type="application/json">{"enable":true,"theme":{"light":"default","dark":"dark"},"js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mermaid/9.1.3/mermaid.min.js","integrity":"sha256-TIYL00Rhw/8WaoUhYTLX9SKIEFdXxg+yMWSLVUbhiLg="}}</script>
  <script src="/js/third-party/tags/mermaid.js"></script>

  <script src="/js/third-party/fancybox.js"></script>


  





</body>
</html>
